from flask import request

from info import constants, db
from info.models import User, News, Category, Comment, CommentLike
from info.utitls.response_code import RET
from . import news_blu
from flask import render_template, session, current_app, jsonify, g
from info.utitls.common import user_login_data

"""
-----------------------------点赞，　取消点赞后端接口------------------------------------------
１，获取参数
    １．１　１，user: 用户对象，　２，comment_id : 评论ｉｄ　　３，ａｃｔｉｏｎ：点赞和取消点赞的
２，校验参数
    ２．１　非空判断
    ２．２action in ["add", "remove"]

３，逻辑处理
    3.0 comment_id查询出当前评论对象
    3.1 根据action行为点赞或者取消点赞
    点赞：创建CommentLike对象，将属性赋值
    取消点赞：CommentLike对象从数据库删除
４，返回值
"""
@news_blu.route('/comment_like', methods=["POST"])
@user_login_data
def comment_like():
    # １．１　１，user: 用户对象，　２，comment_id : 评论ｉｄ　　３，ａｃｔｉｏｎ：点赞和取消点赞的
    user = g.user
    if not user:
        current_app.logger.error("用户未登录")
        return jsonify(errno=RET.SESSIONERR, errmsg="用户未登录")
    param_dict = request.json
    comment_id = param_dict.get("comment_id")
    action = param_dict.get("action")
    # ２．１　非空判断
    if not all([comment_id, action]):
        current_app.logger.error("参数不足")
        return jsonify(errno=RET.PARAMERR, errmsg="参数不足")
    # ２．２action in ["add", "remove"]
    if action not in ["add", "remove"]:
        current_app.logger.error("参数错误")
        return  jsonify(errno=RET.PARAMERR, errmsg="参数错误")

    # 3.0 comment_id查询出当前评论对象
    try:
        comment = Comment.query.get(comment_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="查询评论对象异常")
    if not comment:
        return jsonify(errno=RET.NODATA, errmsg="评论不存在，不允许点赞")

    # 3.1 根据action行为点赞或者取消点赞
    if action == "add":
        # 查询用户是否点赞
        comment_like = None
        try:
            comment_like = CommentLike.query.filter(CommentLike.comment_id == comment.id,CommentLike.user_id == user.id).first()
                # 那条评论点的赞
                # CommentLike.comment_id == comment.id,
                # # 点赞的是那个用户
                # CommentLike.user_id == user.id
        except Exception as e:
            current_app.logger.error(e)
            return jsonify(errno=RET.DBERR, errmsg="查询评论点赞中间表对象异常")
        if not comment_like:
            # 如果没有点赞，那就创建点赞对象
            commentLike_ojb = CommentLike()
            commentLike_ojb.comment_id = comment_id
            commentLike_ojb.user_id = user.id
            comment.like_count += 1
            db.session.add(commentLike_ojb)
    else:
        comment_like = None
        try:
            comment_like = CommentLike.query.filter(CommentLike.comment_id == comment.id,CommentLike.user_id == user.id).first()
        except Exception as e:
            current_app.logger.error(e)
            return jsonify(errno=RET.DBERR, errmsg="查询评论点赞中间表对象异常")

        if comment_like:
            db.session.delete(comment_like)
            comment.like_count -= 1
    try:
        db.session.commit()
    except Exception as e:
            current_app.logger.error(e)
      # 回滚
            db.session.rollback()

    return jsonify(errno=RET.DBERR, errmsg="查询用户对象异常")
      # 4.返回值

    return jsonify(errno=RET.OK, errmsg="OK")






"""
 #  ----------------------新闻收藏---------------------------------------------------
新闻收藏: 目的:经过一系列的逻辑判断处理，使用关系字段的方式，将目的新闻添加到新闻收藏列表中．
１，获取参数
    １．１　news_id,   user:当前用户　　active:收藏，或者是取消收藏

２，校验参数
    2.1 非空约定
    ２．２　判断ａｃｔｉｖｅ： collect, cancel_collect
３，逻辑处理
    3.1 根据新闻ｉｄ获取新闻对象
    ３．２　根据ａｃｔｉｖｅ判断是否收藏
    ３．３修改操作保存到哦数据库
４，返回值

"""
@news_blu.route('/news_collect', methods=["POST"])
@user_login_data
def news_collect():
    #  ----------------------新闻收藏---------------------------------------------------
    #  １．１　news_id, user: 当前用户　　action: 收藏，或者是取消收藏
    user = g.user
    if not user:
        current_app.logger.error("用户未登录")
        return jsonify(errno=RET.SESSIONERR, errmsg="用户未登录")
    params_dict = request.json
    new_id = params_dict.get("news_id")
    action = params_dict.get("action")
    # 2.1 非空约定
    if not all([new_id, action]):
        current_app.logger.error("参数不足")
        return jsonify(errno=RET.PARAMERR, errmsg="参数不足")
    # ２．２　判断ａｃｔｉｖｅ： collect, cancel_collect
    if action not in ["collect", "cancel_collect"]:
        current_app.logger.error("参数错误")
        return jsonify(errno=RET.PARAMERR, errmsg="参数错误")
    # 3.1 根据新闻ｉｄ获取新闻对象
    try:
        news = News.query.get(new_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="查询新闻对象异常")
       # 这是新闻不存在
    if not news:
        return jsonify(errno=RET.NODATA, errmsg="新闻不存在")

    #  ３．２　根据ａｃｔｉｖｅ判断是否收藏
    if action == "collect":
        # user.collection_news:  当前用户收藏的所有新闻．
        user.collection_news.append(news)
    else:
        if news not in user.collection_news:
            user.collection_news.remove(news)
    # ３．３修改操作保存到哦数据库
    try:
        # 数据库提交
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        # 数据库回滚
        db.session.rollback()
        return jsonify(errno=RET.DBERR, errmsg="查询用户对象异常")
    # 4 返回值
    return jsonify(errno=RET.OK, errmsg="OK")




"""
主评论字评论接口：目的：经过一系列的逻辑判断和处理，采用创建表单对象的方式，将目的新闻的评论保存到数据库中．
１，获取参数
    １．１　１，当前用户，　２，当前新闻ｉｄ，　３，ｃｏｍｍｅｍｔ：评论内容，　４，主评论ｉｄ（非毕传）
２，非空判断
３，逻辑处理
    ３．１　获取new_id 对象
    ３．２　创建评论模型
    ３．３　保存数据库中
４，返回值
"""
@news_blu.route('/news_comment', methods=["POST"])
@user_login_data
def news_comment():
    # １．１　１，当前用户，　２，当前新闻ｉｄ，　３，ｃｏｍｍｅｍｔ：评论内容，　４，主评论ｉｄ（非
    user = g.user
    if not user:
        current_app.logger.error("用户未登录")
        return jsonify(errno=RET.SESSIONERR, errmsg="用户未登录")
    param_dict = request.json
    news_id = param_dict.get("news_id")
    comment_str = param_dict.get("comment")
    # 如果有值表示是子评论，如果没值就是主评论
    parent_id = param_dict.get("parent_id")
    # ２，非空判断
    if not all([news_id, comment_str]):
        current_app.logger.error("参数不足")
        return jsonify(errno=RET.PARAMERR, errmsg="参数不足")
    #  ３．１　获取new_id 对象
    try:
        news = News.query.get(news_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="查询新闻对象异常")
    if not news:
        return jsonify(errno=RET.NODATA, errmsg="新闻不存在，不能发表评论")
    # ３．２　创建评论模型
    comment = Comment()
    comment.user_id = user.id
    comment.news_id = news.id
    comment.content = comment_str
    if parent_id:
        comment.parent_id = parent_id
    # ３．３　保存数据库中
    try:
        db.session.add(comment)
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="保存评论对象异常")
    # 返回值
    # 注意;评论完毕后注意将数据返回给前端
    return jsonify(errno=RET.OK, errmsg="OK", data=comment.to_dict())







# 127.0.0.1/news/1  1：代表新闻id
@news_blu.route('/<int:news_id>')
@user_login_data
def get_news_detail(news_id):
    """展示新闻详情页面"""
    # ----------------1. 查询用户登录信息，进行展示------------------------
    # 获取当前登录用户的user_id
    user = g.user

    # 将用户对象数据转换成字典数据，借助模板展示
    # if user:
    #     user_dict = user.to_dict()

    # ----------------2. 查询新闻点击排行数据------------------------

    try:
        news_rank_list = News.query.order_by(News.clicks.desc()).limit(constants.CLICK_RANK_MAX_NEWS)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="查询新闻数据异常")
    """
       新闻对象列表 转换成 新闻字典列表
       news_rank_list ==> [news_obj, news_obj1, ....]
       news_dict_list ==> [news_dict,news_dict1,.....]

        if news_rank_list:
            for news_obj in news_rank_list:
                # 新闻对象转换成字典
                news_dict = news_obj.to_dict()
                news_dict_list.append(news_dict)
    """
    news_dict_list = []
    for news_obj in news_rank_list if news_rank_list else []:
        # 新闻对象转换成字典
        # news_dict = news_obj.to_dict()
        # news_dict_list.append(news_dict)
        news_dict1 = news_obj.to_dict()
        news_dict_list.append(news_dict1)
    # ----------------3. 根据新闻id查询新闻数据 ------------------------
    try:
        news = News.query.get(news_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="查询新闻对象异常")

    # 新闻对象转字典
    news_dict = None
    if news:
        news_dict = news.to_dict()

    # ----------------4. 查询当前用户是否有收藏新闻------------------------
    # 标志当前用户是否收藏过该新闻，默认中：False表示没有收藏
    is_collected = False

    # 当前新闻是否在当前用户新闻收藏列表中
    # if news in user.collection_news:
    #     is_collected = True
    # 当前用户处于登录状态才能查询是否收藏
    if user:
        if news in user.collection_news:
            is_collected = True


    # -----------------5,获取新闻评论列表数据------------------------------------------
    try:
        news_comment_list = Comment.query.filter(Comment.news_id == news_id).all()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="查询用户对象异常")
    # comment_dict_list = []
    # for comment_obj in news_comment_list if news_comment_list else []:
    #     # 评论对象转化成为字典
    #     comment_dict = comment_obj.to_dict()
    #     comment_dict_list.append(comment_dict)
    #

        # -----------------------6,查询当前用户对那几条评论点过赞------------------------
    commentlike_id_list = []
    if user:
        # 这是当前新闻下的所由评论，　news_comment_list：评论对象列表
        comment_id_list = [comment.id for comment in news_comment_list]
    try:
        commentlike_obj_list = CommentLike.query.filter(CommentLike.comment_id.in_(comment_id_list),
                                                        CommentLike.user_id == user.id
                                                        ).all()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="查询用户对象异常")
    # ３，获得所以点赞过的评论ｉｄ
    commentlike_id_list = [commentlike_obj.comment_id for commentlike_obj in commentlike_obj_list]



    # 对象列表转字典列表
    comment_dict_list = []
    for comment_obj in news_comment_list if news_comment_list else []:
        # 评论对象转字典
        comment_dict = comment_obj.to_dict()
        comment_dict["is_like"] = False
        # 遍历每一个评论对象获取其id对比看是否在评论点赞列表中
        # comment_obj1.id == 1 ==> in [1,3,5] ==> is_like=True
        # comment_obj2.id == 2 ==> in [1,3,5] ==> is_like=False
        # comment_obj3.id == 3 ==> in [1,3,5] ==> is_like=True
        if comment_obj.id in commentlike_id_list:
            comment_dict["is_like"] = True
        comment_dict_list.append(comment_dict)


    # 首页数据字典
    data = {
        "user_info": user.to_dict() if user else None,
        "news_rank_list": news_dict_list,
        "news": news_dict,
        "is_collected": is_collected,
        "comments": comment_dict_list

    }
    return render_template("news/detail.html", data=data)